﻿using Ldt.DataEngine.DataFlowParse.Model;
using LdtDataEngin.Moudle;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.Collection;
using LdtJudge.DataEngine.Model.CommModel;
using LdtJudge.DataEngine.Model.DataModel.DataParseStorage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Ldt.DataEngin.Assemble
{
    /// <summary>
    /// 底层分析的入口；
    /// </summary>
    internal class MainBaseNew
    {
        #region 基础信息
        
        /// <summary>
        /// 输入参数
        /// </summary>
        private MainInputParameterModel inputParameter;

        /// <summary>
        /// 上下文
        /// </summary>
        public DataContext dataContext;
        #endregion


        public MainBaseNew(MainInputParameterModel inputPara) 
        {
            inputParameter = inputPara;
        }

        /// <summary>
        /// 数据提取
        /// </summary>
        /// <param name="configModels">分析流程模块集合</param>
        public void Extract(List<ConfigModel> configModels)
        {
            //IMoudle moudle= this.FlowBuild(configModels.Select(a => a.Code).ToList());
            IMoudle moudle= this.FlowBuildNew(configModels);
            dataContext.DataLayerAns.FengXiCanShu = new LdtJudge.DataEngine.Model.DataModel.DataParseStorage.An_fengxicanshu();

            #region  对上下文的基础变量做赋值，主要与输入参数inputParameter做对应
            dataContext.DataLayerAns.CauseId = inputParameter.CaseCause;
            dataContext.DataLayerAns.CaseType = inputParameter.CaseType;
            dataContext.DataLayerAns.CourtId = inputParameter.CourtId;
            dataContext.DataLayerAns.AppId = inputParameter.AppId;
            dataContext.DataLayerAns.MsgId = inputParameter.MsgID;
            dataContext.DataLayerAns.SF_ID = inputParameter.SF_ID;
            dataContext.DataLayerAns.FL_ID = inputParameter.FL_ID;
            dataContext.DataLayerAns.CaseId = inputParameter.CaseID;
            dataContext.DataLayerAns.SourceCode = inputParameter.DocID;
            dataContext.DataLayerAns.IsParagraphAnalysis = inputParameter.IsParagraphAnalysis;
            #endregion

            dataContext.DataLayerAns.FengXiCanShu.Anjianleixing = inputParameter.CaseType;
            dataContext.DataLayerAns.FengXiCanShu.Fayuanid = inputParameter.CourtId;
            dataContext.DataLayerAns.FengXiCanShu.Fl_id = inputParameter.FL_ID;
            dataContext.DataLayerAns.FengXiCanShu.Juanzongbianhao = inputParameter.DocID;
            dataContext.DataLayerAns.FengXiCanShu.Yingyongid = inputParameter.AppId;
            dataContext.DataLayerAns.FengXiCanShu.Canshuid = Snowflake.Instance().GetId().ToString();
            if(inputParameter.IsParagraphAnalysis==true)
            {
                if(inputParameter.ParagraphModels!=null && inputParameter.ParagraphModels.Any())
                {
                    foreach (var item in inputParameter.ParagraphModels)
                    {
                        An_duanluo duanluo = new An_duanluo();
                        duanluo.Duanluoid = Snowflake.Instance().GetId().ToString();
                        duanluo.Duanluoneirong = item.ParagraphContent?.Replace("\\r\\n",Environment.NewLine)?.Replace("\\r", Environment.NewLine)?.Trim();
                        duanluo.Duanluobianhao = item.ParagraphCode?.ToLower();
                        if (dataContext.DataLayerAns.Duanluos == null)
                            dataContext.DataLayerAns.Duanluos = new List<An_duanluo>();
                        if (!dataContext.DataLayerAns.Duanluos.Any(x=>x.Duanluobianhao== item.ParagraphCode.ToLower()))
                            dataContext.DataLayerAns.Duanluos.Add(duanluo);
                    }
                }
            }
            else
            {
                dataContext.DataLayerAns.FengXiCanShu.Juanzongneirong = inputParameter.SourceContent.Replace("&#x13;", "").Replace("&#x14;", "").Replace("&#x15;", "").Replace("&#xD;", "");
            }
            
            //案件信息
            dataContext.DataLayerAns.Anjianxinxi = new An_anjianxinxi()
            {
                Anhao ="",
                Anjianid = inputParameter.CaseID,
                Anjianleixing = inputParameter.CaseType,
                Fayuanid = "",
                Gengxinshijian = DateTime.Now,
                Zhuangtai = 1
            };
            //实例化案件数据内容对象
            dataContext.DataLayerAns.Shujuneirong = new An_shujuneirong()
            {
                Anjianid = inputParameter.CaseID,
                Fl_id = inputParameter.FL_ID,
                Sf_id = inputParameter.SF_ID,
                Shujuid = Snowflake.Instance().GetId().ToString(),
                //Jieduan = "",
                Shujuyuanbianhao = inputParameter.DocID,
                Shujuyuandierbiaoshi = "",
                Shujuyuanleixing = 1,
                //Shujuyuanmingcheng = ""
                Shujuyuanzhuangtai = 1
            };

            //// 流程配置中的模块配置添加到上下文中
            //configModels.Sort((x, y) => Convert.ToInt32(x.Number).CompareTo(Convert.ToInt32(y.Number)));
            //foreach (var item in configModels)
            //{
            //    dataContext.DataLayerSys.SetConfigModel(item.Code,item);
            //}

            //执行数据提取
            moudle.MoudleHandle(dataContext);
        }
        
        /// <summary>
        ///  案件优选
        /// </summary>
        /// <param name="configModels">案件优选流程</param>
        public void Optimization()
        {
           dataContext = new DataContext(dataContext.DataLayerSys, dataContext.DataLayerAns, new DyData_Optimize(), dataContext.InteractiveShow);
            #region  对上下文的基础变量做赋值，主要与输入参数inputParameter做对应
            dataContext.DataLayerOpt.CauseId = inputParameter.CaseCause;
            dataContext.DataLayerOpt.CaseType = inputParameter.CaseType;
            dataContext.DataLayerOpt.CourtId = inputParameter.CourtId;
            dataContext.DataLayerOpt.AppId = inputParameter.AppId;
            dataContext.DataLayerOpt.MsgId = inputParameter.MsgID;
            dataContext.DataLayerOpt.CaseId = inputParameter.CaseID;
            dataContext.DataLayerOpt.SignId = string.Empty;
            dataContext.DataLayerOpt.Anjianxinxi = dataContext.DataLayerAns.Anjianxinxi;
            #endregion

           
        }
        /// <summary>
        /// 根据模块生成流程信息
        /// </summary>
        /// <param name="moudlelist">模块集合</param>
        /// <returns></returns>
        private IMoudle FlowBuildNew(List<ConfigModel> moudlelist)
        {
            FlowCombination flowCombination = new FlowCombination();

            foreach (var moudleitem in moudlelist)
            {
                //添加模块；
                flowCombination.AddMoudle((next) =>
                {
                    //进行实例化模块
                    var mo=this.CreatAssemblyMoudle<IMoudle>(moudleitem.Code, "LdtDataEngin.Moudle", next);
                    //将配置信息也都赋值到配置信息中
                    dataContext.DataLayerSys.SetConfigModel(moudleitem.Code+"_"+mo.GetHashCode(), moudleitem);
                    return mo;
                });
            }
            //生成流程管道;
            IMoudle firstMoudle = flowCombination.BuildFlow();
            return firstMoudle;
        }
        /// <summary>
        /// 执行模块的添加，以及流程生成；
        /// </summary>
        [Obsolete("该方法无法应对同一个模块被多次调用问题")]
        private IMoudle FlowBuild(List<string> moudlelist) 
        {
            FlowCombination flowCombination = new FlowCombination();
            //List<string> moudlelist = new List<string>();

            foreach (var moudleitem in moudlelist)
            {
                //添加模块；
                flowCombination.AddMoudle((next) =>
                {
                    //进行实例化模块
                   return this.CreatAssemblyMoudle<IMoudle>(moudleitem, "LdtDataEngin.Moudle", next);
                    //MoudleExample moudle = new MoudleExample(next);
                    //return moudle;
                });
            }
            //生成流程管道;
            IMoudle firstMoudle=flowCombination.BuildFlow();
            return firstMoudle;
            ////执行第一个模块；
            //DataContext dataContext = new DataContext();
            //firstMoudle.MoudleHandle(dataContext);
        }

        /// <summary>MoudleMergerSameSource
        /// 根据模块名称进行反射创建实例对象
        /// </summary>
        /// <typeparam name="T">模块名称</typeparam>
        /// <param name="fullName">模块全路径</param>
        /// <param name="assemblyName">模块名称</param>
        /// <param name="nextMoudle">下一个模块对象</param>
        /// <returns></returns>
        private T CreatAssemblyMoudle<T>(string fullName,string assemblyName,IMoudle nextMoudle)
        {
           
            string path = fullName + "," + assemblyName;//命名空间.类型名,程序集
            Type ob = Type.GetType(path);//加载类型
            object[] parameters = new object[1];
            parameters[0] = nextMoudle;
            object obj = Activator.CreateInstance(ob, parameters);//根据类型创建实例
            return (T)obj;//类型转换并返回
        }

        /// <summary>
        /// 解析案由要素定位配置信息
        /// </summary>
        /// <param name="configContent"></param>
        /// <returns></returns>
        //private List<LocationModel> ParseCaseCauseLocationConfig(string configContent)
        //{
        //    List<LocationModel> re = new List<LocationModel>();
        //    XDocument xdoc = XDocument.Parse(configContent);
        //    XElement root = xdoc.Root;
        //    foreach (XElement booktype in root.Elements("booktype"))
        //    {
        //        LocationModel locationModel = new LocationModel();
        //        if (booktype.Attribute("code") != null)
        //        {
        //            locationModel.DocType = booktype.Attribute("code").Value;
        //        }
        //        if (booktype.Attribute("path") != null)
        //        {
        //            locationModel.DocPath = booktype.Attribute("path").Value;
        //        }
        //        if (booktype.Attribute("number") != null)
        //        {
        //            locationModel.Number = Convert.ToInt32(booktype.Attribute("number").Value);
        //        }
        //        foreach (XElement element in booktype.Elements("element"))
        //        {
        //            if (element.Attribute("path") != null)
        //            {
        //                locationModel.EelementPaht = element.Attribute("path").Value;
        //            }
        //        }
        //        foreach (XElement element in booktype.Elements("mergelement"))
        //        {
        //            if (element.Attribute("path") != null)
        //            {
        //                locationModel.MergeElmentPath = element.Attribute("path").Value;
        //            }
        //        }
        //        foreach (XElement element in booktype.Elements("reasonelement"))
        //        {
        //            string caseCauseRoute = string.Empty;
        //            if (element.Attribute("path") != null)
        //            {
        //                locationModel.ReasoneELementPath = element.Attribute("path").Value;
        //            }
        //        }
        //        re.Add(locationModel);
        //    }
        //    return re;
        //}

        ///// <summary>
        ///// 初始化上下文
        ///// </summary>
        ///// <param name="dataContext"></param>
        ///// <returns></returns>
        //private DataContext InitDataContext(DataContext dataContext, string operateType)
        //{
        //    if (operateType.ToLower() == "any")
        //    {
        //        dataContext.DataLayerSys = new DataLayerSysStores();
        //        dataContext.DataLayerAns = new DyData_Analysis();
        //        dataContext.InteractiveShow = new InteractiveShowClass();
        //    }
        //    else
        //    {

        //    }
        //    return dataContext;
        //}
    }
}
